Skip to content

Method: lambda$createGame$0(InputProvider, Map)

1: package de.fhdw.gaming.core.domain.util;
2:
3: import java.util.Iterator;
4: import java.util.List;
5: import java.util.Map;
6: import java.util.Optional;
7:
8: import de.fhdw.gaming.core.domain.Game;
9: import de.fhdw.gaming.core.domain.GameBuilder;
10: import de.fhdw.gaming.core.domain.GameBuilderFactory;
11: import de.fhdw.gaming.core.domain.GameException;
12: import de.fhdw.gaming.core.domain.Move;
13: import de.fhdw.gaming.core.domain.Player;
14: import de.fhdw.gaming.core.domain.State;
15: import de.fhdw.gaming.core.domain.Strategy;
16: import de.fhdw.gaming.core.ui.InputProvider;
17: import de.fhdw.gaming.core.ui.InputProviderException;
18: import de.fhdw.gaming.core.ui.util.ChainedInputProvider;
19: import de.fhdw.gaming.core.ui.util.NonInteractiveInputProvider;
20:
21: /**
22: * Helper facade for creating a default {@link Game} given a {@link GameBuilderFactory}.
23: */
24: public final class GameBuilderFacade {
25:
26: /**
27: * Private constructor.
28: */
29: private GameBuilderFacade() {
30: // nothing to do
31: }
32:
33: /**
34: * Creates a {@link GameBuilder} given the desired type of a {@link GameBuilderFactory}.
35: *
36: * @param <GB> The desired type of a {@link GameBuilder}.
37: * @param <GBF> The desired type of a {@link GameBuilderFactory}.
38: * @param <P> The expected type of a {@link Player}.
39: * @param <S> The expected type of a {@link State}.
40: * @param <M> The expected type of a {@link Move}.
41: * @param <ST> The expected type of a {@link Strategy}.
42: * @param type The desired {@link Class} of the {@link GameBuilder} to return.
43: * @param gameBuilderFactories An iterator over all available {@link GameBuilderFactory} objects.
44: * @param strategy A {@link Strategy} to use for all players. If empty, the
45: * {@link GameBuilderFactory} is asked for all available strategies, and the first
46: * available one is used for the players.
47: * @param maxComputationTimePerMove The maximum number of seconds a strategy can use for choosing a move.
48: * @return The {@link GameBuilder} or {@link Optional#empty()} if either {@link GameBuilderFactory game builder
49: * factories} or {@link Strategy strategies} are unavailable.
50: */
51: public static <GB extends GameBuilder, GBF extends GameBuilderFactory, P extends Player<P>, S extends State<P, S>,
52: M extends Move<P, S>, ST extends Strategy<P, S, M>> Optional<GB> createGameBuilder(final Class<GB> type,
53: final Iterable<GBF> gameBuilderFactories, final Optional<ST> strategy,
54: final int maxComputationTimePerMove)
55: throws InputProviderException, GameException {
56:
57: final Iterator<GBF> gbfIter = gameBuilderFactories.iterator();
58: if (!gbfIter.hasNext()) {
59: return Optional.empty();
60: }
61:
62: final GBF gameBuilderFactory = gbfIter.next();
63:
64: final ST gameStrategy;
65: if (strategy.isPresent()) {
66: gameStrategy = strategy.orElseThrow();
67: } else {
68: @SuppressWarnings("unchecked")
69: final List<ST> strategies = (List<ST>) gameBuilderFactory.getStrategies();
70: if (strategies.isEmpty()) {
71: return Optional.empty();
72: }
73: gameStrategy = strategies.get(0);
74: }
75:
76: return Optional.of(createGame(type, gameBuilderFactory, gameStrategy, maxComputationTimePerMove));
77: }
78:
79: /**
80: * Creates a {@link GameBuilder} from a {@link GameBuilderFactory} and an optional {@link Strategy}.
81: *
82: * @param <GB> The desired type of a {@link GameBuilder}.
83: * @param <GBF> The type of a {@link GameBuilderFactory}.
84: * @param <P> The expected type of a {@link Player}.
85: * @param <S> The expected type of a {@link State}.
86: * @param <M> The expected type of a {@link Move}.
87: * @param <ST> The expected type of a {@link Strategy}.
88: * @param type The desired {@link Class} of the {@link GameBuilder} to return.
89: * @param gameBuilderFactory The {@link GameBuilderFactory} to use.
90: * @param strategy The {@link Strategy} to use. If empty, the first available one is used.
91: * @param maxComputationTimePerMove The maximum number of seconds a strategy can use for choosing a move.
92: * @return The {@link GameBuilder} or {@link Optional#empty()} if either {@link GameBuilderFactory game builder
93: * factories} or {@link Strategy strategies} are unavailable.
94: */
95: private static <GB extends GameBuilder, GBF extends GameBuilderFactory, P extends Player<P>, S extends State<P, S>,
96: M extends Move<P, S>, ST extends Strategy<P, S, M>> GB createGame(final Class<GB> type,
97: final GBF gameBuilderFactory, final ST strategy, final int maxComputationTimePerMove)
98: throws InputProviderException, GameException {
99:
100: InputProvider mostRecentProvider = null;
101: int nextPlayerId = gameBuilderFactory.getMinimumNumberOfPlayers();
102: while (nextPlayerId > 0) {
103: final InputProvider lastPlayerProvider = mostRecentProvider;
104: final InputProvider playerInputProvider = lastPlayerProvider == null ? new NonInteractiveInputProvider()
105: : new ChainedInputProvider(
106: new NonInteractiveInputProvider(),
107: (final Map<String, Object> lastDataSet) -> lastPlayerProvider);
108:
109: playerInputProvider.fixedString(GameBuilderFactory.PARAM_PLAYER_NAME, Integer.toString(nextPlayerId--));
110: playerInputProvider.fixedObject(GameBuilderFactory.PARAM_PLAYER_STRATEGY, strategy);
111: mostRecentProvider = playerInputProvider;
112: }
113:
114: final InputProvider firstPlayerProvider = mostRecentProvider;
115: final InputProvider gameInputProvider = firstPlayerProvider == null ? new NonInteractiveInputProvider()
116: : new ChainedInputProvider(
117: new NonInteractiveInputProvider(),
118: (final Map<String, Object> lastDataSet) -> firstPlayerProvider);
119: gameInputProvider
120: .fixedInteger(GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE, maxComputationTimePerMove);
121:
122: return type.cast(gameBuilderFactory.createGameBuilder(gameInputProvider));
123: }
124: }